package com.xh.core.util;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/*
 * @Author daiwei
 * @Description
 * @Date 2018/8/11 11:50
 **/
public class DateUtils {

    public static void main(String[] args) throws ParseException {
        Pattern pattern=Pattern.compile("font-size:[1-9][0-9]*([\\.][0-9]{1,2})?pt", Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher("adads%font-size:12pt%asdfas");
        if (matcher.find()) {
            System.out.println(matcher.group(1));
        }
    }
	
    /**
     * 获得今天日期对象
     * @return
     */
    public static Date getTodayDate() {
        Calendar cal = new GregorianCalendar();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }
    public static Date getDateStart(Date date) {
        Calendar cal = new GregorianCalendar();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        return cal.getTime();
    }
    public static Date getDateEnd(Date date) {
        Calendar cal = new GregorianCalendar();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        return cal.getTime();
    }
    /**
     * 时间戳转日期对象
     * @param value 时间戳，Unix时间，不包括毫秒
     * @return
     */
    public static Date parseUnixToDate(long value){
        return parseTimestampToDate(value*1000);
    }


    /**
     * 时间戳转日期对象
     * @param value 时间戳，包含毫秒
     * @return
     */
    public static Date parseTimestampToDate(long value){
        SimpleDateFormat format =  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Long time=new Long(value);
        String d = format.format(time);
        Date date= null;
        try {
            date = format.parse(d);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

	/**
	 * 字符串转日期对象
	 * @param date
	 * @param pattern
	 * @return
	 * @throws ParseException 
	 */
	public static Date parseDate(String date,String pattern) {
        try {
            SimpleDateFormat format = new SimpleDateFormat(pattern);
            return format.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 字符串转日期对象
     * @param date
     * @param pattern
     * @return
     */
    public static Date parse(String date,String pattern){
        DateTimeFormatter format = DateTimeFormat.forPattern(pattern);
        return DateTime.parse(date,format).toDate();
    }


    /**
     * 日期对象格式化输出字符串
     * @param date
     * @param pattern
     * @return
     */
    public static String format(Date date,String pattern){
        SimpleDateFormat fmt = new SimpleDateFormat(pattern);
        return fmt.format(date);
    }


    /**
     * 获取日期对象的纯日期部分
     * @param date
     * @return
     */
    public static Date getDatePart(Date date){
        SimpleDateFormat format =  new SimpleDateFormat("yyyy-MM-dd");
        String result=format.format(date);
        try {
            return format.parse(result);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 日期分钟调整
     * @param d
     * @param num
     * @return
     */
    public static Date dateAddForMin(Date d, int num) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
        cal.add(Calendar.MINUTE, num);
        return cal.getTime();
    }


    /**
     * 日期按天调整
     * @param d
     * @param num
     * @return
     */
    public static Date dateAddForDay(Date d, int num) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
        cal.add(Calendar.DATE, num);
        return cal.getTime();
    }


    /**
     * 某月第一天的日期：相对于当前日期
     * @param month 0：表示当前月
     * @return
     */
    public static Date getFirstDayMonth(int month){
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MONTH, month);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        return parse(format(cal.getTime(),"yyyy-MM-dd"),"yyyy-MM-dd") ;
    }


    /**
     * 获取时间的年月日
     * @param startDate 时间
     * @param field 字段
     * @return
     */
    public static Integer getDateField(Date startDate, int field) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(startDate);
        return cal.get(field);
    }


    /**
     * 1 第一季度 2 第二季度 3 第三季度 4 第四季度
     *
     * @param date
     * @return
     */
    public static int getSeason(Date date) {

        int season = 0;

        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int month = c.get(Calendar.MONTH);
        switch (month) {
            case Calendar.JANUARY:
            case Calendar.FEBRUARY:
            case Calendar.MARCH:
                season = 1;
                break;
            case Calendar.APRIL:
            case Calendar.MAY:
            case Calendar.JUNE:
                season = 2;
                break;
            case Calendar.JULY:
            case Calendar.AUGUST:
            case Calendar.SEPTEMBER:
                season = 3;
                break;
            case Calendar.OCTOBER:
            case Calendar.NOVEMBER:
            case Calendar.DECEMBER:
                season = 4;
                break;
            default:
                break;
        }
        return season;
    }


    /**
     * 根据时间，生成以年月日+毫秒计算的时间
     * @return
     */
    public static String getDateTimeStr() {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
        Date date = new Date();
        date.getTime();
        String formatdate = fmt.format(date);
        return String.valueOf(formatdate + date.getTime());
    }
    
    /**
     * 确定一年中某一周的开始日期
     * @param year
     * @param weekNo
     * @return
     */
    public static String getStartDayOfWeekNo(int year,int weekNo){
        Calendar cal = getCalendarFormYear(year);
        cal.set(Calendar.WEEK_OF_YEAR, weekNo);
        return cal.get(Calendar.YEAR) + "-" + (cal.get(Calendar.MONTH) + 1) + "-" +
                cal.get(Calendar.DAY_OF_MONTH);
    }
    /**
     * 确定一年中某一周的结束日期
     * @param year
     * @param weekNo
     * @return
     */
    public static String getEndDayOfWeekNo(int year,int weekNo){
        Calendar cal = getCalendarFormYear(year);
        cal.set(Calendar.WEEK_OF_YEAR, weekNo);
        cal.add(Calendar.DAY_OF_WEEK, 6);
        return cal.get(Calendar.YEAR) + "-" + (cal.get(Calendar.MONTH) + 1) + "-" +
                cal.get(Calendar.DAY_OF_MONTH);
    }
    
    /**
     * get Calendar of given year
     * @param year
     * @return
     */
    private static Calendar getCalendarFormYear(int year){
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        cal.set(Calendar.YEAR, year);
        return cal;
    }

    // 获取当前时间所在月的开始日期
    public static Date getFirstDayOfMonth(Date date) {
        Calendar c = new GregorianCalendar();
        c.setTime(date);
        //设置为1号,当前日期既为本月第一天
        c.set(Calendar.DAY_OF_MONTH, 1);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return c.getTime();
    }

    // 获取当前时间所在月的结束日期
    public static Date getLastDayOfMonth(Date date) {
        Calendar c = new GregorianCalendar();
        c.setTime(date);
        //设置为当月最后一天
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        c.set(Calendar.HOUR_OF_DAY, 23);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);
        return c.getTime();
    }

    /**
     * 时间调整
     * @param dateField 6日 3周 2月
     */
    public static Date offset(Date date, int dateField, int offset) {
        Calendar cal = Calendar.getInstance();
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        cal.setTime(date);
        cal.add(dateField, offset);
        return cal.getTime();
    }

    /**
     * 某个日期所在的日（周，月）的开始时间
     * @param dateField 6日 3周 2月
     */
    public static Date begin(Date date, int dateField) {
        return beginOrEnd(date, dateField, true);
    }

    /**
     * 某个日期所在的日（周，月）的结束时间
     * @param dateField 6日 3周 2月
     */
    public static Date end(Date date, int dateField) {
        return beginOrEnd(date, dateField, false);
    }

    private static Date beginOrEnd(Date date, int dateField, boolean begin) {
        Calendar cal = Calendar.getInstance();
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        cal.setTime(date);
        List<Integer> ignoreFields = Arrays.asList(11, 9, 8, 6, 4, 3);
        for(int i = dateField + 1; i <= 14; ++i) {
            if (!ignoreFields.contains(i)) {
                if (4 != dateField && 3 != dateField) {
                    if (7 == i) {
                        continue;
                    }
                } else if (5 == i) {
                    continue;
                }
                if (10 == i) {
                    i = 11;
                }
                if(begin) {
                    cal.set(i, getBeginValue(cal, i));
                } else {
                    cal.set(i, getEndValue(cal, i));
                }
            }
        }
        return cal.getTime();
    }

    private static int getBeginValue(Calendar calendar, int dateField) {
        return 7 == dateField ? calendar.getFirstDayOfWeek() : calendar.getActualMinimum(dateField);
    }

    private static int getEndValue(Calendar calendar, int dateField) {
        return 7 == dateField ? (calendar.getFirstDayOfWeek() + 6) % 7 : calendar.getActualMaximum(dateField);
    }

    /**
     * Date转LocalDate
     * @param date
     */
    public static LocalDate date2LocalDate(Date date) {
        if(null == date) {
            return null;
        }
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
    }

    /***
     *  功能描述：日期转换cron表达式
     * @param date
     * @param dateFormat : e.g:yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static String formatDateByPattern(Date date,String dateFormat){
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        String formatTimeStr = null;
        if (date != null) {
            formatTimeStr = sdf.format(date);
        }
        return formatTimeStr;
    }
    /***
     * convert Date to cron ,eg.  "0 07 10 15 1 ? 2016"
     * @param date  : 时间点
     * @return
     */
    public static String getCron(java.util.Date  date){
        String dateFormat="ss mm HH dd MM ? yyyy";
        return formatDateByPattern(date, dateFormat);
    }

}
